#pragma once

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <fstream>
#include "msli/common/config.h"
#include "msli/model/PolynomialRegression.hpp"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
class Point {
public:
    OID_TYPE id{};
    std::vector<T> coords;

    // 默认构造函数
    Point() = default;

    ~Point() = default;

    // 带参数的构造函数, 初始化 coords 和 id
    explicit Point(const std::vector<T> &coords, OID_TYPE OId) : id(OId) {
        if (coords.empty()) {
            throw std::invalid_argument("coords vector cannot be empty");
        }
        this->coords = coords;
    }

    // 拷贝赋值操作符
    Point<T> &operator=(const Point<T> &other) {
        if (this != &other) { // 避免自我赋值
            id = other.id;
            coords = other.coords;
        }
        return *this;
    }

    // 按 oid 升序排序
    bool operator<(const Point<T> &other) const {
        return id < other.id;
    }

    // 计算距离
    T distance(const Point<T> &other) const {
        T sum = 0;
        for (size_t i = 0; i < coords.size(); ++i) {
            sum += (coords[i] - other.coords[i]) * (coords[i] - other.coords[i]);
        }
        return std::sqrt(sum);
    }

    // 输出点信息的方法
    void Print(std::ostream &os) const {
        os << std::fixed << std::setprecision(6);
        for (int i = 0; i < coords.size(); ++i) {
            if (i == coords.size() - 1)
                os << coords[i] << std::endl;
            else
                os << coords[i] << ",";
        }
    }
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 点对及距离的结构体(用于最小堆)
struct Edge {
    DIS_TYPE distance;
    OID_TYPE point1_id, point2_id;

    bool operator>(const Edge &other) const {
        return distance > other.distance;
    }
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
